﻿using System;
using System.Collections.Generic;

using SBPweb.PhotoGallery.Common;

namespace SBPweb.PhotoGallery.Client.Logic
{

    public class AdvancingGallery : Gallery<FetchableSlide>
    {

        #region Private fields

        protected int currentIndex = 0;
        protected bool autoRepeat = true;

        #endregion

        #region Constructor logic

        public AdvancingGallery()
            : base()
        {
        }

        public AdvancingGallery(string basePath)
            : base(basePath)
        {
        }

        public AdvancingGallery(FetchableSlide[] slides, string basePath)
            : base(slides, basePath)
        {
        }

        public AdvancingGallery(FetchableSlide[] slides, string basePath, int? pageIndex, int? pageSize)
            : base(slides, basePath, pageIndex, pageSize)
        {
        }

        ~AdvancingGallery()
        {
            FinalizeHandlers();
        }

        protected override void InitializeHandlers()
        {
            base.InitializeHandlers();
            this.ItemAdded += new EventHandler<OverridableList<FetchableSlide>.ItemEventArgs>(AdvancingGallery_ItemAdded);
            this.ItemRemoved += new EventHandler<OverridableList<FetchableSlide>.ItemEventArgs>(AdvancingGallery_ItemRemoved);
        }

        protected override void FinalizeHandlers()
        {
            base.FinalizeHandlers();
        }

        #endregion

        #region Property accessors

        public int CurrentIndex
        {
            get
            {
                return currentIndex;
            }
        }

        public bool AutoRepeat
        {
            get
            {
                return autoRepeat;
            }
            set
            {
                autoRepeat = value;
            }
        }

        protected FetchableSlide CurrentSlide
        {
            get
            {
                if (this.Count > currentIndex && currentIndex >= 0)
                {
                    return this[currentIndex];
                }
                return null;
            }
        }

        #endregion

        #region Events

        public event EventHandler<SlideFetchProgressEventArgs> ImageFetching;

        public event EventHandler<SlideFetchEventArgs> ImageFetched;

        public event EventHandler<SlideFetchProgressEventArgs> ThumbnailFetching;

        public event EventHandler<SlideFetchEventArgs> ThumbnailFetched;

        #endregion

        #region Methods

        protected virtual void CopyContextToItem(Dictionary<string, object> context)
        {
            context["BaseUri"] = BasePath;
        }

        public void FetchFirstSlide()
        {
            FetchSlide(0);
        }

        public void FetchPreviousSlide()
        {
            FetchSlide(currentIndex - 1);
        }

        public void FetchCurrentSlide()
        {
            FetchSlide(currentIndex);
        }

        public void FetchSlide(int index)
        {
            int firstIndex = 0;
            int lastIndex = this.Count - 1;
            if (index < 0)
            {
                index = autoRepeat ? lastIndex : firstIndex;
            }
            if (index >= this.Count)
            {
                index = autoRepeat ? firstIndex : lastIndex;
            }
            currentIndex = index;
            CurrentSlide.FetchImage();
        }

        public void FetchNextSlide()
        {
            FetchSlide(currentIndex + 1);
        }

        public void FetchLastSlide()
        {
            FetchSlide(this.Count - 1);
        }

        protected virtual void OnImageFetching(object sender, SlideFetchProgressEventArgs e)
        {
            if (ImageFetching != null)
            {
                ImageFetching(this, e);
            }
        }

        protected virtual void OnImageFetched(object sender, SlideFetchEventArgs e)
        {
            if (ImageFetched != null)
            {
                ImageFetched(this, e);
            }
        }

        protected virtual void OnThumbnailFetching(object sender, SlideFetchProgressEventArgs e)
        {
            if (ThumbnailFetching != null)
            {
                ThumbnailFetching(this, e);
            }
        }

        protected virtual void OnThumbnailFetched(object sender, SlideFetchEventArgs e)
        {
            if (ThumbnailFetched != null)
            {
                ThumbnailFetched(this, e);
            }
        }

        private void AdvancingGallery_ItemAdded(object sender, OverridableList<FetchableSlide>.ItemEventArgs e)
        {
            CopyContextToItem(e.Item.Context);
            e.Item.ImageFetching += new EventHandler<SlideFetchProgressEventArgs>(OnImageFetching);
            e.Item.ImageFetched += new EventHandler<SlideFetchEventArgs>(OnImageFetched);
            e.Item.ThumbnailFetching += new EventHandler<SlideFetchProgressEventArgs>(OnThumbnailFetching);
            e.Item.ThumbnailFetched += new EventHandler<SlideFetchEventArgs>(OnThumbnailFetched);
        }

        private void AdvancingGallery_ItemRemoved(object sender, OverridableList<FetchableSlide>.ItemEventArgs e)
        {
            e.Item.ImageFetching -= new EventHandler<SlideFetchProgressEventArgs>(OnImageFetching);
            e.Item.ImageFetched -= new EventHandler<SlideFetchEventArgs>(OnImageFetched);
            e.Item.ThumbnailFetching -= new EventHandler<SlideFetchProgressEventArgs>(OnThumbnailFetching);
            e.Item.ThumbnailFetched -= new EventHandler<SlideFetchEventArgs>(OnThumbnailFetched);
        }

        #endregion

    }

}